package cn.px.service.upms.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.px.common.enums.ScheduleStatus;
import cn.px.dao.dto.upms.ScheduleJobDTO;
import cn.px.dao.entity.upms.ScheduleJob;
import cn.px.dao.mapper.upms.ScheduleJobMapper;
import cn.px.service.base.impl.BaseServiceImpl;
import cn.px.service.bean.ScheduleUtils;
import cn.px.service.upms.ScheduleJobService;
import lombok.AllArgsConstructor;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 任务表 service 实现类
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2019,北京乾元坤和科技有限公司 All rights reserved.
 */
@Service("scheduleJobService")
@AllArgsConstructor
public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJobMapper, ScheduleJob, ScheduleJobDTO> implements ScheduleJobService {

    private final Scheduler scheduler;

    /**
     * 项目启动时，初始化定时器
     */
    @PostConstruct
    public void init() {
        List<ScheduleJob> scheduleJobList = mapper.selectAll();
        for (ScheduleJob scheduleJob : scheduleJobList) {
            CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId());
            //如果不存在，则创建
            if (cronTrigger == null) {
                ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
            } else {
                ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScheduleJob saveModelByDTO(ScheduleJobDTO scheduleJobDTO) {
        ScheduleJob scheduleJob = new ScheduleJob();
        BeanUtil.copyProperties(scheduleJobDTO, scheduleJob);
        scheduleJob.setCreatedTime(LocalDateTime.now());
        scheduleJob.setStatus(ScheduleStatus.NORMAL.getValue());
        mapper.insert(scheduleJob);
        ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
        return scheduleJob;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modModelByPrimaryKey(ScheduleJob scheduleJob) {
        ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
        mapper.updateByPrimaryKeySelective(scheduleJob);
    }

    /**
     * 根据主键更新属性不为null的值
     *
     * @param model
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modModelByDTO(ScheduleJobDTO model) {
        ScheduleJob scheduleJob = new ScheduleJob();
        BeanUtil.copyProperties(model, scheduleJob);
        ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
        mapper.updateByPrimaryKeySelective(scheduleJob);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] jobIds) {
        for (Long jobId : jobIds) {
            ScheduleUtils.deleteScheduleJob(scheduler, jobId);
        }
        //删除数据
        mapper.deleteBatch(jobIds);
    }

    @Override
    public int updateBatch(Long[] jobIds, int status) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("list", jobIds);
        map.put("status", status);
        return mapper.updateBatch(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(Long[] jobIds) {
        for (Long jobId : jobIds) {
            ScheduleUtils.run(scheduler, mapper.selectByPrimaryKey(jobId));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pause(Long[] jobIds) {
        for (Long jobId : jobIds) {
            ScheduleUtils.pauseJob(scheduler, jobId);
        }
        updateBatch(jobIds, ScheduleStatus.PAUSE.getValue());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resume(Long[] jobIds) {
        for (Long jobId : jobIds) {
            ScheduleUtils.resumeJob(scheduler, jobId);
        }
        updateBatch(jobIds, ScheduleStatus.NORMAL.getValue());
    }
}
